from typing import List
from pandas import DataFrame
import pandas as pd

import pymongo
from bson import ObjectId
from connector.stockConnector import stockConnector
from model.scenario import Scenario
from datetime import datetime
import uuid


from utils.databaseConfig import databaseConfig
class ScenarioConnector:
    def __init__(self) -> None:
        client = pymongo.MongoClient(databaseConfig.database_url)
        db = client[databaseConfig.database_name]
        self.collection = db["scenarios"]
        
        
    def getScenariosList(self) -> List[Scenario]:
        scenario_list = []
        for i in self.collection.find():
            temp_scenario = Scenario(str(i['_id']),i['name'],i['description'],i['image'])
            for j in i['attribute_list']:
                temp_scenario.addAttribute({
                    "index":j['index'],
                    "label":j['label']
                })
            scenario_list.append(temp_scenario)
        return scenario_list
    
    def getItemByUuid(self,scenario_id,item_uuid)->dict:
        query = {"_id":ObjectId(scenario_id)}
        item_list = self.collection.find_one(query)['item_list']
        temp_item = {
            "uuid":item_uuid,
            "name":None,
            "start_date":None,
            "end_date":None
        }
        for i in item_list:
            if i['uuid'] == uuid.UUID(item_uuid):
            # if i['uuid'].as_uuid(3) == uuid.UUID(item_uuid):
                temp_item['name'] = i['name']
                temp_item['start_date'] = i['start_date']
                temp_item['end_date'] = i['end_date']
            
        return temp_item
    
    def addScenario(self,new_scenario:dict)->None:
        self.collection.insert_one(new_scenario)
        return
    
    def addScenarioItem(self,new_scenario_item,scenario_id)->None:
        query = {"_id":ObjectId(scenario_id)}
        new_scenario_item['start_date'] =  datetime.fromtimestamp((new_scenario_item['start_date']/1000))
        new_scenario_item['end_date'] =  datetime.fromtimestamp((new_scenario_item['end_date']/1000))
        new_scenario_item['uuid'] = uuid.uuid4()
        self.collection.update_one(query,{'$push': {'item_list': new_scenario_item}})
        return
    
    def getScenarioById(self,id)->Scenario:
        query = {"_id": ObjectId(id)}
        temp_item = self.collection.find_one(query)
        temp_scenario = Scenario(str(temp_item['_id']),temp_item['name'],temp_item['description'],temp_item['image'])
        for j in temp_item['attribute_list']:
            temp_scenario.addAttribute({
                    "index":j['index'],
                    "label":j['label']
            })
        for k in temp_item['item_list']:
            temp_item_item = {
                "uuid":str(k['uuid']),
                "name":k['name'],
                "stock_code":k['stock_code'],
                "stock_name":stockConnector.getStockNameByCode(k['stock_code']),
                "item_type":k['item_type'],
                "start_date":k['start_date'].timestamp(),
                "end_date":k['end_date'].timestamp(),
                "attribute_list":[]
                }
            for l in k['attribute_list']:
                temp_item_item["attribute_list"].append({
                    "label":l['label'],
                    "index":l['index'],
                    "value":l['value']
                })
            temp_scenario.addItem(temp_item_item)
        return temp_scenario
    
    
    def getAttributeDataInRange(self,scenario_id:str,attribute_name:str,start_date:datetime,end_date:datetime)->DataFrame:
        query = {"_id":ObjectId(scenario_id)}
        df = None
        for i in self.collection.find_one(query)["attribute_list"]:
            if i["label"] == attribute_name:
                df = DataFrame(i["data"])
        df = df[df['date'].between(start_date, end_date)]
        df.sort_values('date', inplace=True)
        df.reset_index(drop=True)
        return df
    
    def getAttributeDataOnDate(self,scenario_id:str,attribute_name:str,date:datetime)->float:
        query = {"_id":ObjectId(scenario_id)}
        df = None
        for i in self.collection.find_one(query)["attribute_list"]:
            if i["label"] == attribute_name:
                df = DataFrame(i["data"])

        return float((df[df['date'] == date].iloc[0,1]))
    
    
scenarioConnector = ScenarioConnector()
    